package cn.iocoder.yudao.module.wms.service.inventory;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.wms.controller.admin.inventory.vo.InventoryPageReqVO;
import cn.iocoder.yudao.module.wms.controller.admin.inventory.vo.InventorySaveReqVO;
import cn.iocoder.yudao.module.wms.dal.dataobject.inventory.InventoryDO;
import cn.iocoder.yudao.module.wms.dal.dataobject.inventoryclassify.InventoryClassifyDO;
import cn.iocoder.yudao.module.wms.dal.mysql.inventory.InventoryMapper;
import cn.iocoder.yudao.module.wms.service.inventoryclassify.InventoryClassifyService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.wms.enums.ErrorCodeConstants.*;

/**
 * 存货档案 Service 实现类
 *
 * @author 曾劲松
 */
@Service
@Validated
public class InventoryServiceImpl implements InventoryService {

    @Resource
    private InventoryMapper inventoryMapper;
    @Resource
    private InventoryClassifyService inventoryClassifyService;

    @Override
    public Long createInventory(InventorySaveReqVO createReqVO) {
        validateCodeOrNameExists(createReqVO);
        // 插入
        InventoryDO inventory = BeanUtils.toBean(createReqVO, InventoryDO.class);
        inventoryMapper.insert(inventory);
        // 返回
        return inventory.getId();
    }

    @Override
    public void updateInventory(InventorySaveReqVO updateReqVO) {
        // 校验存在
        validateInventoryExists(updateReqVO.getId());
        validateCodeOrNameExists(updateReqVO);
        // 更新
        InventoryDO updateObj = BeanUtils.toBean(updateReqVO, InventoryDO.class);
        inventoryMapper.updateById(updateObj);
    }

    @Override
    public void deleteInventory(Long id) {
        // 校验存在
        validateInventoryExists(id);
        // 删除
        inventoryMapper.deleteById(id);
    }

    private void validateInventoryExists(Long id) {
        if (inventoryMapper.selectById(id) == null) {
            throw exception(INVENTORY_NOT_EXISTS);
        }
    }

    /**
     * 校验编码或名称是否存在
     * @param reqVO 存货Request VO
     */
    private void validateCodeOrNameExists(InventorySaveReqVO reqVO) {
        if (inventoryMapper.selectCount(InventoryDO::getCode, reqVO.getCode()) > 0) {
            throw exception(INVENTORY_CODE_EXISTS);
        }
        if (inventoryMapper.selectCount(InventoryDO::getName, reqVO.getName()) > 0) {
            throw exception(INVENTORY_NAME_EXISTS);
        }
    }

    @Override
    public InventoryDO getInventory(Long id) {
        return inventoryMapper.selectById(id);
    }

    @Override
    public PageResult<InventoryDO> getInventoryPage(InventoryPageReqVO pageReqVO) {
        return inventoryMapper.selectPage(pageReqVO, getClassifyCondition(pageReqVO.getClassifyId()));
    }

    @Override
    public List<InventoryDO> getInventorySimpleList(String query) {
        return inventoryMapper.selectList(query);
    }

    /**
     * 获得存货分类条件：查询指定存货分类的子分类编号们，包括自身
     *
     * @param classifyId 存货分类编号
     * @return 存货分类编号集合
     */
    private Set<Long> getClassifyCondition(Long classifyId) {
        if (classifyId == null) {
            return Collections.emptySet();
        }
        Set<Long> classifyIds = convertSet(inventoryClassifyService.getChildInventoryClassifyList(classifyId), InventoryClassifyDO::getId);
        classifyIds.add(classifyId); // 包括自身
        return classifyIds;
    }
}